package momo.app.status;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import momo.app.comms.CommsManager;
import momo.app.config.AppConfig;
import momo.app.structure.Message;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class LatencyPoolThread extends Thread
{
	private Log log = LogFactory.getLog(LatencyPoolThread.class);
	
	private final long UPDATE_INTERVAL = 1 * 30 * 1000;
	
	public LatencyPoolThread()
	{
		this.start();
	}
	
	synchronized static public void updateLatency()
	{
		Vector<String> toRemove = new Vector<String>();
		
		
		String source_id = AppConfig.getInstance().getId();
		
		Collection<LatencyMeasurement> set = StatusManager.getInstance().getLatMeasureMap();
		Iterator<LatencyMeasurement> iter = set.iterator();
		while ( iter.hasNext() )
		{
			LatencyMeasurement latMeasurement = iter.next();
			double lat = latMeasurement.getMeasuredLatency();
			
			double costFromChildToMe = latMeasurement.getMeasuredPeer().getUserCost(AppConfig.getInstance().getId());
			double costFrmMeToChild = AppConfig.getInstance().getUserCost(latMeasurement.getMeasuredPeer().getId());
			double cost = costFromChildToMe + costFrmMeToChild;
			
//			add or update links info
			
			String dest_id = latMeasurement.getMeasuredPeer().getId();
			String toSend = source_id+","+dest_id+","+cost+","+lat;
			
			Log log = LogFactory.getLog(LatencyPoolThread.class);
			if ( log.isDebugEnabled() )
				log.debug("add/update link: " + toSend);
			
//			if lat < 0 remove the link and latMeasurement from graph else add/update
			if ( lat < 0 )
			{
				StatusManager.getInstance().removePeerLink(source_id, dest_id);
				toRemove.add(latMeasurement.getMeasuredPeer().getId());
			}else
				StatusManager.getInstance().addPeerLink(source_id, dest_id, cost, lat);
			
			//for testing
			StatusManager.getInstance().displayPeerLink();
			
//			propagate these info to the rest
			CommsManager.getInstance().sourceForward(
					new Message(
							Message.NO_FORWARD, 
							source_id, 
							Message.UPDATE_PEER_LINK, 
							toSend),
							false
					);
		}
		
		for(String id : toRemove )
			StatusManager.getInstance().removeLatMeasureThread(id);
	}
	
	public void run()
	{
		boolean interrupted = false;
		while ( !interrupted )
		{
			updateLatency();
			try
			{
				Thread.sleep(UPDATE_INTERVAL);
			}catch(InterruptedException ie)
			{
				interrupted = true;
				if ( log.isErrorEnabled() )
					log.error("InterruptedException", ie);
			}
		}
	}
}//end of class LatencyPoolThread
